# FASTAPI
from fastapi import FastAPI, Depends, HTTPException
import uvicorn
from fastapi.exceptions import RequestValidationError
from fastapi.staticfiles import StaticFiles
from fastapi.openapi.docs import get_swagger_ui_html
from fastapi.middleware.cors import CORSMiddleware
from tortoise.contrib.fastapi import register_tortoise
from starlette.responses import JSONResponse
from pydantic import ValidationError

from MyOAuth import my_oauth2_scheme
from api.customer_api import customer_router
from api.sys_user_api import sys_user_router
from api.warehouse_api import warehouse_router
from api.product_api import product_router
from api.sale_api import sale_router
from api.move_api import move_router
from ApiResponse import ApiResponse  # 导入上面定义的响应类
from db.settings import TORTOISE_ORM
from LogConfig import blogLogger  # LogConfig中的代码会自动执行
from exception.customException import OperateException

# 正常实例化API操作
app = FastAPI(
    title='凌瑞商贸',
    description='APP接口',
    version='0.0.1',
    docs_url=None,
    redoc_url=None,  # 设置 ReDoc 文档的路径
)


@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc: HTTPException):
    return JSONResponse(
        status_code=exc.status_code,
        content=ApiResponse.error(exc.status_code, exc.detail).dict()
    )


@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc: RequestValidationError):
    return JSONResponse(
        status_code=500,
        content=ApiResponse.error(500, "数据不合法", data=exc.errors()).dict()
    )


@app.exception_handler(OperateException)
async def Operate_exception_handler(request, exc: OperateException):
    return JSONResponse(
        status_code=200,
        content=ApiResponse.error(exc.code, exc.message).dict()
    )


@app.exception_handler(Exception)
async def Exception_handler(request, _exception):
    content: dict = ApiResponse.error(500, "系统错误，请联系管理员").dict()
    return JSONResponse(
        status_code=500,
        content=content
    )


# register_tortoise是集成TortoiseORM到FastAPI应用中
# add_exception_handlers=True，则tortoiseORM的异常由fastapi处理
# add_exception_handlers=False，则tortoiseORM的异常由自己编写处理器处理
# generate_schemas=True,则根据模型数据库模型（不需要，因为用aerich处理）
register_tortoise(
    app,
    db_url=TORTOISE_ORM["connections"]["default"],
    modules={"models": TORTOISE_ORM["apps"]["models"]["models"]},
    add_exception_handlers=False,
    generate_schemas=False,
)

# 跨域处理 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 允许所有源，也可以指定特定源
    allow_credentials=True,
    allow_methods=["*"],  # 允许所有方法
    allow_headers=["*"],  # 允许所有头
)

# 挂载静态资源 如果自己要访问某资源的话就是 http://127.0.0.1:8080/static/swagger/img.png
app.mount("/static", StaticFiles(directory="static"), name="static")
app.include_router(sys_user_router, prefix="/sysUser", tags=["用户相关接口"], dependencies=[Depends(my_oauth2_scheme)])
app.include_router(customer_router, prefix="/customer", tags=["客户相关接口"], dependencies=[Depends(my_oauth2_scheme)])
app.include_router(warehouse_router, prefix="/warehouse", tags=["仓库相关接口"],
                   dependencies=[Depends(my_oauth2_scheme)])
app.include_router(product_router, prefix="/product", tags=["产品相关接口"])
app.include_router(sale_router, prefix="/sale", tags=["销售订单相关接口"])
app.include_router(move_router, prefix="/move", tags=["调拨订单相关接口"], dependencies=[Depends(my_oauth2_scheme)])


# 接口文档JS CSS文件从本项目走，不走CSDN
@app.get("/apidoc", include_in_schema=False)
async def custom_swagger_ui_html():
    return get_swagger_ui_html(
        openapi_url="/openapi.json",
        title="接口文档",
        # oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
        swagger_js_url='/static/swagger/swagger-ui-bundle.js',
        swagger_css_url='/static/swagger/swagger-ui.css',
        swagger_favicon_url='/static/swagger/img.png',
    )


if __name__ == '__main__':
    uvicorn.run("main:app",host="192.168.101.36", port=8080, reload=True)
